<?php

/**
 * Mediad co,ltd
 *
 * @category   Mediad2
 * @package    Mediad2_Service
 * @subpackage Util
 * @copyright  Copyright (c) 2012 Mediad co,ltd. (http://www.Mediad.cn)
 * @license    New BSD License
 * @version    $Id: Dict.php 1 2012-06-14 16:18:00Z tany@Mediad.cn $
 */

/**
 * Mediad2_Service_Admin
 * Mediad2_Model
 */
require_once 'Mediad2/Service/Admin/Dict.php';

/**
 * @category   Mediad2
 * @package    Service
 * @subpackage Util
 */
class Mediad2_Service_Util_Dict extends ArrayObject 
{
	/**
	 * Class name of the singleton Dict object.
	 * @var string
	 */
	private static $_DictClassName = 'Mediad2_Service_Util_Dict';
	
	/**
	 * DictUtil object provides storage for shared objects.
	 * @var Mediad2_Service_Util_Dict
	 */
	private static $_DictUtil = null;
	
	/**
	 * Retrieves the default DictUtil instance.
	 *
	 * @return Mediad2_Service_Util_Dict
	 */
	public static function getInstance()
	{
		if (self::$_DictUtil === null) {
			self::init();
		}
	
		return self::$_DictUtil;
	}
	
	/**
	 * Set the default DictUtil instance to a specified instance.
	 *
	 * @param Mediad2_Service_Util_Dict $DictUtil An object instance of type Mediad2_Service_Util_Dict,
	 *   or a subclass.
	 * @return void
	 * @throws Mediad2_Service_Exception if registry is already initialized.
	 */
	public static function setInstance(Mediad2_Service_Util_Dict $DictUtil)
	{
		if (self::$_DictUtil !== null) {
			require_once 'Mediad2/Service/Exception.php';
			throw new Mediad2_Service_Exception('DictUtil is already initialized');
		}
	
		self::setClassName(get_class($DictUtil));
		self::$_DictUtil = $DictUtil;
	}
	
	/**
	 * Initialize the default DictUtil instance.
	 *
	 * @return void
	 */
	protected static function init()
	{
		self::setInstance(new self::$_DictClassName());
	}
	
	/**
	 * Set the class name to use for the default DictUtil instance.
	 * Does not affect the currently initialized instance, it only applies
	 * for the next time you instantiate.
	 *
	 * @param string $DictClassName
	 * @return void
	 * @throws Mediad2_Service_Exception if the registry is initialized or if the
	 *   class name is not valid.
	 */
	public static function setClassName($DictClassName = 'Mediad2_Service_Util_Dict')
	{
		if (self::$_DictUtil !== null) {
			require_once 'Mediad2/Service/Exception.php';
			throw new Mediad2_Service_Exception('$_DictUtil is already initialized');
		}
	
		if (!is_string($DictClassName)) {
			require_once 'Mediad2/Service/Exception.php';
			throw new Mediad2_Service_Exception("Argument is not a class name");
		}
	
		/**
		 * @see Zend_Loader
		 */
		if (!class_exists($DictClassName)) {
			require_once 'Zend/Loader.php';
			Zend_Loader::loadClass($DictClassName);
		}
	
		self::$_DictClassName = $DictClassName;
	}
	
	/**
	 * Unset the default $_DictUtil instance.
	 * Primarily used in tearDown() in unit tests.
	 * @returns void
	 */
	public static function _unsetInstance()
	{
		self::$_DictUtil = null;
	}
	
	/**
	 * getter method, basically same as offsetGet().
	 *
	 * This method can be called from an object of type Mediad2_Service_Util_Dict, or it
	 * can be called statically.  In the latter case, it uses the default
	 * static instance stored in the class.
	 *
	 * @param string $index - get the value associated with $index
	 * @return mixed
	 * @throws Mediad2_Service_Exception if no entry is registerd for $index.
	 */
	public static function get($index)
	{
		$instance = self::getInstance();
	
		if (!$instance->offsetExists($index)) {
			require_once 'Mediad2/Service/Exception.php';
			throw new Mediad2_Service_Exception("No entry is registered for key '$index'");
		}
	
		return $instance->offsetGet($index);
	}
	
	/**
	 * setter method, basically same as offsetSet().
	 *
	 * This method can be called from an object of type Zend_Registry, or it
	 * can be called statically.  In the latter case, it uses the default
	 * static instance stored in the class.
	 *
	 * @param string $index The location in the ArrayObject in which to store
	 *   the value.
	 * @param mixed $value The object to store in the ArrayObject.
	 * @return void
	 */
	public static function set($index, $value)
	{
		$instance = self::getInstance();
		$instance->offsetSet($index, $value);
	}
	
	/**
	 * Returns TRUE if the $index is a named value in the registry,
	 * or FALSE if $index was not found in the registry.
	 *
	 * @param  string $index
	 * @return boolean
	 */
	public static function isRegistered($index)
	{
		if (self::$_DictUtil === null) {
			return false;
		}
		return self::$_DictUtil->offsetExists($index);
	}
	
	/**
	 * Constructs a parent ArrayObject with default
	 * ARRAY_AS_PROPS to allow acces as an object
	 *
	 * @param array $array data array
	 * @param integer $flags ArrayObject flags
	 */
	public function __construct($array = array(), $flags = parent::ARRAY_AS_PROPS)
	{
		parent::__construct($array, $flags);
	}
	
	/**
	 * @param string $index
	 * @returns mixed
	 *
	 * Workaround for http://bugs.php.net/bug.php?id=40442 (ZF-960).
	 */
	public function offsetExists($index)
	{
		return array_key_exists($index, $this);
	}
	
	/**
	 * 获得指定字典类型代码的字典
	 * @param string $dictTypeCode
	 * @return mixed data 
	 */
	public static function getId($dictTypeCode)
	{
		$instance = self::getInstance();
		$dicts = array();
		
		//判断在内存中是否存在指定的字典类型代码
		if ($instance->isRegistered($dictTypeCode)) {	
			//从内存中获取
			$dicts = $instance->get($dictTypeCode);
		} else {
			//从数据库中获取
			$where = null;
			//$where = " DictStatus = '1' ";	//字典状态为“正常”
			$serviceDict = new Mediad2_Service_Admin_Dict();
			$dicts = $serviceDict->getDictsByDictTypeCode($dictTypeCode,$where);
			if (!empty($dicts)) {
				//更新内存
				$instance->set($dictTypeCode, $dicts);
			} else {
				require_once 'Mediad2/Service/Exception.php';
				throw new Mediad2_Service_Exception("未定义字典类型代码 '$dictTypeCode'");
			}
		}
		
		return $dicts;
	}
	
	/**
	 * 获得指定字典代码的字典
	 * @param string $dictCode
	 * @return Mediad2_Model_GloDictInfo
	 */
	public static function getDictByCode($dictCode)
	{
		$instance = self::getInstance();
		$dict = new Mediad2_Model_Dict();
		if ($instance->isRegistered($dictCode)) {	//判断在内存中是否存在指定的字典类型代码
			//从内存中获取
			$dict = $instance->get($dictCode);
		} else {
			//从数据库中获取
			$condition = null;
			//$condition = " DictStatus = '1' ";	//字典状态为“正常”
			$dictService = new Mediad2_Service_Admin_Dict();
			$condition = "code = '$dictCode'";
			$result = $dictService->findBy($condition);
			if ($result->getCode()==$result::CODE_SUCCESS) {
				$dict = $result->getData();
				if (!empty($dict)) {
					$instance->set($dictCode, $dict); //更新内存
				} else {
					require_once 'Mediad2/Service/Exception.php';
					throw new Mediad2_Service_Exception("未定义字典代码 '$dictCode'");
				}
			}
		}
	
		return $dict;
	}
	
}